import nprogress from 'nprogress';
import { useHistory } from 'react-router-dom'
import moment from 'moment';
import BigNumber from 'bignumber.js';
import { bigDiv, bigDivGetInteger, isGt, isLess } from './bigNumber';
import type { INftLoopTimeType } from '@/interface';
import { NftLoopTimeTypeEnum } from '@/enum';

// 切换路由
// export const toPage = (path?: string, parmas?: any) => {
//   nprogress.start();
//   if (path) {
//     const { push, location: { pathname } } = useHistory()
//     push(path, { state: parmas });
//   }
//   window.scrollTo(0, 0);
// };

export const getInviteCode = () => {
  let code: string = ''
  if (window.location.href.indexOf("?inviteCode=") != -1) {
    const arr = window.location.href.split("?inviteCode=")
    if (!!arr && arr.length === 2) {
      code = arr[1]
      localStorage.setItem("parentInviteCode", code)
    }
  }
  return code
}

export const getInviteNodeCode = () => {
  let code: string = ''
  if (window.location.href.indexOf("inviteCode=") != -1) {
    const arr = window.location.href.split("inviteCode=")
    if (!!arr && arr.length === 2) {
      code = arr[1]
    }
  }
  return code
}

export const addressLenghtChange = (address: string, endNumber = 4, startNumber = 6) => {
  if (!address) return '-';
  const length = address.length;
  return `${address.substring(0, startNumber)}...${address.substring(
    length - endNumber,
    length,
  )}`;
}

export const addressLenghtChangeStar = (address: string, endNumber = 4, startNumber = 6) => {
  if (!address) return '-';
  const length = address.length;
  return `${address.substring(0, startNumber)}***${address.substring(
    length - endNumber,
    length,
  )}`;
}


const twoWeiTime = (time: any) => {
  if (time.toString().length == 1) {
    return '0' + time;
  }
  return time;
};

export const getFormatDate = (str: string) => {
  const date = new Date(str)
  const year = date.getFullYear()
  const month = date.getMonth() + 1;
  const day = date.getDate()
  const result = year + '-' + month + "-" + day
  return str ? result : ''
}

export const getFormatDateHourMinut = (str: string) => {
  let result = ''
  if (str) {
    const date = new Date(str)
    const year = date.getFullYear()
    const month = date.getMonth() + 1;
    const day = date.getDate()
    const hour = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
    const minute = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
    result = year + '/' + month + "/" + day + " " + hour + ":" + minute
  }
  return str ? result : ''
}

//时间格式化将new Date()对象转换为00:00:00格式
export const getAllTimeFormat = (now: Date, split = '-') => {
  let year = now.getFullYear(); //年
  let month = now.getMonth() + 1; //月
  let day = now.getDate(); //日
  let hh = now.getHours(); //时
  let mm = now.getMinutes(); //分
  let ss = now.getSeconds(); //秒
  let clock = ''
  if (split) {
    clock = year + split;
    if (month < 10) {
      clock += "0";
    }
    clock += month + split;
    if (day < 10) {
      clock += "0";
    }
  } else {
    clock = year + '-';
    if (month < 10) {
      clock += "0";
    }
    clock += month + '-';
    if (day < 10) {
      clock += "0";
    }
  }
  clock += day + " ";
  if (hh < 10) {
    clock += "0";
  }
  clock += hh + ":";
  if (mm < 10) {
    clock += "0";
  }
  clock += mm + ":";
  if (ss < 10) {
    clock += "0";
  }
  clock += ss;
  return clock;
}



export const getTime = (endTime: string | number) => {
  let now = moment().valueOf();
  let end = moment(endTime).valueOf();
  let diff = moment(end).diff(now);

  if (now > end) {
    return {
      days: 0,
      hours: 0,
      mins: 0,
      secs: 0,
      interOver: true,
    };
  }
  let days = twoWeiTime(moment.duration(diff).days());

  let hours = twoWeiTime(moment.duration(diff).hours());

  let mins = twoWeiTime(moment.duration(diff).minutes());

  let secs = twoWeiTime(moment.duration(diff).seconds());
  return {
    days,
    hours,
    mins,
    secs,
    interOver: false,
  };
};

export const getanTime = (endTime: string | number) => {
  endTime = Number(endTime)
  if (endTime <= 0) {
    return {
      days: 0,
      hours: 0,
      mins: 0,
      secs: 0,
      interOver: true,
    };
  }

  let days = twoWeiTime(moment.duration(endTime).days());

  let hours = twoWeiTime(moment.duration(endTime).hours());

  let mins = twoWeiTime(moment.duration(endTime).minutes());

  let secs =
    twoWeiTime(moment.duration(endTime).seconds()) == '00'
      ? '59'
      : twoWeiTime(moment.duration(endTime).seconds());
  return {
    days,
    hours,
    mins,
    secs,
    interOver: false,
  };
};

export const milliseconds = (time: Array<any>) => {
  let all: number = 0;
  if (time && time.length > 0) {
    time.forEach((item, index) => {
      if (index == 0 && item > 0) {
        all = all + item * 24 * 60 * 60 * 1000;
      }
      if (index == 1 && item > 0) {
        all = all + item * 60 * 60 * 1000;
      }
      if (index == 2 && item > 0) {
        all = all + item * 60 * 1000;
      }
      if (index == 3 && item > 0) {
        all = all + item * 1000;
      }
    });
  }
  return all;
};

export const kFormat = (num: string | number) => {
  //千位符
  if (num) {
    var res = num.toString().replace(/\d+/, function (n) {
      // 先提取整数部分
      return n.replace(/(\d)(?=(\d{3})+$)/g, function ($1) {
        return $1 + ',';
      });
    });
    return res;
  }
  return 0;
};

// 保留小数点
export const formatFixed = (arg1: number, arg2: number) => {
  var m = 0;
  var s1 = arg1.toString();
  var s2 = arg2.toString();
  try {
    m += s1.split('.')[1].length;
  } catch (e) { }
  try {
    m += s2.split('.')[1].length;
  } catch (e) { }

  return (
    (Number(s1.replace('.', '')) * Number(s2.replace('.', ''))) /
    Math.pow(10, m)
  );
};

// 获取链接参数
export const fetchUrl = (
  urls: string = window.location.href,
  keyword: string,
) => {
  const url = urls || decodeURIComponent(window.location.href);
  const result: Record<string, string> = {};
  const query = url.split('?')[1];
  if (!query) return '';
  const arr = query.split('&');
  arr.forEach((item) => {
    const key: string = item.split('=')[0];
    result[key] = item.split('=')[1];
  });
  return result[keyword] || '';
};


export function handleThrottle(callback: Function, duration = 70) {
  let throttleTimer: NodeJS.Timeout | null;

  return () => {
    if (throttleTimer) {
      return;
    }
    throttleTimer = setTimeout(() => {
      callback();
      if (throttleTimer) {
        clearTimeout(throttleTimer)
        throttleTimer = null
      }
    }, duration);
  };
}

/**
 * @param distance timestamp
 * @returns
 */
export function formatDate(distance: number) {
  const days = Math.floor(distance / (1000 * 60 * 60 * 24));
  const hours = Math.floor(
    (distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60),
  );
  const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
  const seconds = Math.floor((distance % (1000 * 60)) / 1000);

  return {
    days,
    hours,
    minutes,
    seconds,
  };
}

//  获取指定指定时区时间（北京时区为8，纽约时区为-5。东时区为正数，西市区为负数）
export const getTimeByZone = (timezone = 8, date: Date) => {
  // 本地时间距离（GMT时间）毫秒数
  let nowDate = !date ? new Date().getTime() : new Date(date).getTime()
  // 本地时间和格林威治时间差，单位分钟
  let offset_GMT = new Date().getTimezoneOffset()
  //  反推到格林尼治时间
  let GMT = nowDate + offset_GMT * 60 * 1000
  //  获取指定时区时间
  let targetDate = new Date(GMT + timezone * 60 * 60 * 1000)
  const dateStr = getAllTimeFormat(targetDate)
  return dateStr
}

export const getTimeNumberByZone = (timezone = 8, date: Date) => {
  // 本地时间距离（GMT时间）毫秒数
  let nowDate = !date ? new Date().getTime() : new Date(date).getTime()
  // 本地时间和格林威治时间差，单位分钟
  let offset_GMT = new Date().getTimezoneOffset()
  //  反推到格林尼治时间
  let GMT = nowDate + offset_GMT * 60 * 1000
  //  获取指定时区时间
  let currentBeijingTime = new Date(GMT + timezone * 60 * 60 * 1000).getTime()
  return currentBeijingTime
}

//东八区时间转当前时区时间
export const currentLocalDate = (now: Date) => {
  // 创建一个表示当前时间的Date对象
  // 获取时区偏移量（以分钟为单位）
  const timezoneOffset = now.getTimezoneOffset();
  console.log("偏移量", timezoneOffset)
  // 将偏移量从当前时间中减去，得到当地时间
  const localTime = new Date(now.getTime() - timezoneOffset * 60 * 1000);
  // 输出当地时间
  console.log("result", localTime);
  console.log("result2_time", localTime.getTime());
  return localTime
}
// console.log("输出土耳其时间", currentLocalDate(new Date()))

export const timeDifference = (lastDate: Date) => {

  const nowTime = getTimeNumberByZone(8, new Date())
  //const targetTime = new Date(timestamp);
  const diffInMilliseconds = nowTime - lastDate.getTime();
  const diffInMinutes = diffInMilliseconds / (1000 * 60);
  const diffInHours = diffInMilliseconds / (1000 * 60 * 60);
  const diffInDays = diffInMilliseconds / (1000 * 60 * 60 * 24);
  const diffInMonths = diffInDays / 30;
  const diffInYears = diffInDays / 365;
  const loopObject: INftLoopTimeType = {
    type: '',
    timeStr: ''
  }
  if (diffInMinutes < 60) {
    loopObject.type = NftLoopTimeTypeEnum.MINUTE
    loopObject.timeStr = String(Math.round(diffInMinutes))
    return loopObject; //`${Math.round(diffInMinutes)}分钟前`
  } else if (diffInHours < 24) {
    loopObject.type = NftLoopTimeTypeEnum.HOUR
    loopObject.timeStr = String(Math.round(diffInHours))
    return loopObject;  //`${Math.round(diffInHours)}小时前`
  } else if (diffInDays < 30) {
    loopObject.type = NftLoopTimeTypeEnum.DAY
    loopObject.timeStr = String(Math.round(diffInDays))
    return loopObject;  //`${Math.round(diffInDays)}天前`
  } else if (diffInMonths < 365) {
    loopObject.type = NftLoopTimeTypeEnum.MONTH
    loopObject.timeStr = String(Math.round(diffInMonths))
    return loopObject; //`${Math.round(diffInMonths)}个月前`
  } else {
    loopObject.type = NftLoopTimeTypeEnum.YEAR
    loopObject.timeStr = String(Math.round(diffInYears))
    return loopObject; //`${Math.round(diffInYears)}年前`
  }
}
const cDate = new Date("2023-12-11 14:36:46")
const timeStr = timeDifference(cDate)
console.log("timeStr", timeStr)

/**
 * 相差时间戳 转换为还差多少天 多少分 多少秒
 */
export function timestampFormatDate(instanceTime: number) {
  const dayTime = 24 * 3600 * 1000;
  const hourTime = 60 * 60 * 1000
  const minterTime = 60 * 1000
  const secondTime = 1 * 1000
  const days = Number.parseInt((instanceTime / dayTime).toString())
  const hour = Number.parseInt(((instanceTime - (dayTime * days)) / hourTime).toString())
  const minute = Number.parseInt(((instanceTime - dayTime * days - hour * hourTime) / minterTime).toString())
  const second = Number.parseInt(((instanceTime - dayTime * days - hour * hourTime - minute * minterTime) / secondTime).toString())
  return {
    days,
    hour,
    minute,
    second
  }
}



export function isMobileHandle() {
  return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
    navigator.userAgent,
  );
}

/**
 * 四舍五入 不补0
 */
export function toFixed(number: number, decimals: number) {
  var pow = Math.pow(10, decimals);
  var rounded = Math.round(number * pow) / pow;
  var result = rounded.toString();
  return result;
}

/**
 * 截断小数
 */
export function sliceNum(num: number, decimals: number) {
  const int = num.toString().indexOf('.');
  if (int !== -1) {
    return num.toString().slice(0, int + decimals + 1);
  } else {
    return num;
  }
}

// 保留n位小数但不进行四舍五入
export const parseNumber = (str: string | number, length: number) => {
  const num = (typeof str === 'string') ? parseFloat(str) : str
  return Math.floor(num * Math.pow(10, length)) / Math.pow(10, length);
}

export const toNonExponential = (num: number) => {
  const m: any = num.toExponential().match(/\d(?:\.(\d*))?e([+-]\d+)/);
  const result = !!m ? num.toFixed(Math.max(0, (m[1] || '').length - m[2])) : '0'
  return result;
}

//去掉小数点尾部无效的0
export const formatNumerNoEffectZero = (formattedStr: string) => {
  formattedStr = formattedStr.replace(/(\.\d*?[1-9])0*$/g, '$1').replace(/\.0*$/, '');
  formattedStr = formattedStr.replace(/^,/, '').replace(/\.$/, '')
  // const removeZero = (numStr: string) => {
  //   let index = 0;
  //   for (let i = 0; i < numStr.length; i++) {
  //     if (numStr[i] != '0' && numStr[i] != '.') {
  //       index = i;
  //     }
  //   }
  //   return numStr.substring(0, index + 1)
  // }
  // formattedStr = removeZero(formattedStr)
  return formattedStr
}


export const formatNumberZero = (numberStr: string) => {
  if (typeof numberStr === 'number') { //如果是数字类型 转字符串
    numberStr = ''.concat(numberStr)
  }
  // 去除字符串中的空格和逗号
  numberStr = numberStr.replace(/\s+/g, '')  //replace(/,/g, '');

  // 将字符串转换为浮点数
  //const number = parseFloat(numberStr);
  let numBig = new BigNumber(numberStr)
  let formattedStr = numBig.toFormat()
  // 转换为字符串并去除尾部多余的零
  formattedStr = formattedStr.replace(/(\.\d*?[1-9])0*$/g, '$1');
  formattedStr = formattedStr.replace(/^,/, '').replace(/\.$/, '')
  return formattedStr;
}

// "50,000,000,000" 格式
export const formatNumber = (num: number | string, n = 0) => {
  //return parseNumber(num, 2)
  if (Number.isNaN(num)) {
    num = 0
  }
  if (!num) {
    num = 0
  }
  let numBig = new BigNumber(num)
  const t: string = numBig.toFormat().replace(/(\.\d*?[1-9])0*$/g, '$1')
  const hasDot = t.includes('.')
  const intSeg = hasDot ? t.split('.')[0] : t
  const dotSeg = hasDot ? t.split('.')[1] : ''
  //intSeg.split('').reverse().join('').replace(/[\d]{3}/g, (a) => a + ',').split('').reverse().join('')
  const formattedIntSeg = [intSeg,
    dotSeg.substring(0, n)].join('.')
  const result = formattedIntSeg.replace(/^,/, '').replace(/\.$/, '')
  return result
}

/**
 * 处理k m  b单位展示
 * @param a 
 * @param n 
 * @returns 
 */
export const dealData = (a: number | string, n = 2) => {
  // - 展示跨链空投池地址BNB余额（BNB余额在千位以下需展示小数，保留2位，如286.66 BNB，51.25 BNB。超出千位，不展示小数，如1K）。
  // 并采用四舍五入的展示方式。数量单位用K、M、B表示，分别为千、百万、十亿。
  if (isLess(a, 1000)) {
    return formatNumber(a, n)  //小于1000 保留2位小数 小于1000没单位
  }
  else if (isGt(a, 1000) && isLess(a, 1000000)) { // 1000到100 0000  取k
    return bigDivGetInteger(a, 10 ** 3) + "K" //除以100w
  } else if (isGt(a, 10 ** 6) && isLess(a, 10 ** 9)) {
    //大于 100w取B
    return bigDivGetInteger(a, 10 ** 6) + "M"   // 小于10个亿  10 00000000
  } else {
    return bigDivGetInteger(a, 10 ** 9) + "B"
  }
}
console.log(dealData(100.236, 2))
console.log(dealData(10 * 10 ** 4))
console.log(dealData(8 * 10 ** 6))
console.log(dealData(9 * 10 ** 9))
//测试数据 
console.log("dealData1", dealData(562.23369))  //这时候应该输出 
export const inputFormatNumber = (num: string, n = 0) => {
  //return parseNumber(num, 2)
  if (Number.isNaN(num)) {
    num = ''
    return num
  }
  if (!num) {
    num = ''
    return num
  }
  const t: string = num
  const hasDot = t.includes('.')
  let intSeg = hasDot ? t.split('.')[0] : t
  const dotSeg = hasDot ? t.split('.')[1] : ''
  //intSeg.split('').reverse().join('').replace(/[\d]{3}/g, (a) => a + ',').split('').reverse().join('')
  //如果整数部分  第一位是0 
  if (intSeg.substring(0, 1) === '0' && intSeg.substring(1, 2) !== '.') {
    //console.log("第二位必须为小数点")
    if (intSeg.length >= 2) {
      intSeg = intSeg.substring(1, 2)   // 06 取6
    } else {
      intSeg = '0'  //第二位必须为小数点  //如果第一位跟第二位都为0 直接默认为0
    }
  }
  const formattedIntSeg = [intSeg,
    dotSeg.substring(0, n)].join('.')
  //console.log("输入的值输出", formattedIntSeg)
  const formattedStr = formattedIntSeg.replace(/^,/, '').replace(/\.$/, '')
  let result = formattedStr
  return result
}

//输入框输入数字正则校验
export const number_reg = (decimals: string | number = '') => {
  return RegExp(`^(0|[1-9]\\d*)${decimals === 0 ? '' : `((\\.)?|(\\.\\d{1,${decimals}}))?`}$`);
}

export const getIgoIdExtractValuesFromUrl = () => {
  const pointArr = window.location.href.split("/")
  const igoPoint = pointArr.find((item) => item.indexOf("igo") != -1)
  const paramArr = window.location.href.split("invite?ref=")
  let ref = ''
  let userInviteCode = ''
  if (paramArr[1]) {
    ref = paramArr[1].split("&")[0]
    const afterStr = paramArr[1].split("&")[1]
    userInviteCode = afterStr.split("=")[1]
  }
  return {
    'igoId': igoPoint?.replace("igo", ""),
    'ref': ref,
    userInviteCode: userInviteCode
  };
}

/**
 * 防抖
 *
 * @param {*} func
 * @param {*} wait
 * @param {*} immediate
 * @returns
 */
export const debounce = <T extends (...args: any) => any>(
  fn: T,
  time?: number,
  immediate?: boolean
): ((...args: any) => any) => {
  let timeoutId: any
  let defaultImmediate = immediate || false
  let delay = time || 300
  return (...args: any) => {
    console.log("执行2",defaultImmediate)
    if (defaultImmediate) {
      fn.apply(this, args) // 确保引用函数的指向正确，并且函数的参数也不变
      defaultImmediate = false
      return
    }
    if (timeoutId) {
      clearTimeout(timeoutId)
    }
    timeoutId = setTimeout(() => {
      fn.apply(this, args)
      timeoutId = null
    }, delay)
  }
}



/**
  * 国际数字格式化
  * 支持千分位,小数按照精度舍去，截断(向下保留)
  * @param num
  * @param precision 精度
  */
type IType = string | BigNumber | number;
export function intlFloorFormat(num: IType, precision = 0): string | number {
  if (num === 0 || num == null || num == undefined) {
    return '0.0'
  }
  let result = ''
  let reg = new RegExp(`^\\d+(?:\\.\\d{0,${precision}})?`);
  let trimNum: any = num.toString().match(reg)
  if (trimNum == '0.0000') {
    result = '0.0'
  } else {
    result = trimNum
  }
  return result
}

